import can
import time
import datetime  # 新增datetime导入
from threading import Thread

class VirtualCANBus:
    def __init__(self, bus_name='virtual_can0'):
        self.bus = can.interface.Bus(bustype='virtual', channel=bus_name, bitrate=500000)
        self.running = False
        self.receive_thread = Thread(target=self._receive_messages)
        print(f"虚拟CAN总线 {bus_name} 已初始化")

    def start(self):
        self.running = True
        self.receive_thread.start()
        print("虚拟CAN总线已启动")

    def stop(self):
        self.running = False
        self.receive_thread.join()
        self.bus.shutdown()
        print("虚拟CAN总线已关闭")

    def send_message(self, arbitration_id, data):
        msg = can.Message(arbitration_id=arbitration_id, data=data, is_extended_id=False)
        try:
            self.bus.send(msg)
            # 以下可以输出至终端
            #timestamp = datetime.datetime.now().strftime("%H:%M:%S.%f")[:-3]
            #print(f"[{timestamp}] TX: ID=0x{arbitration_id:03X}, DLC={len(data)}, Data={data.hex(' ').upper()}")
        except can.CanError:
            print("发送消息失败")

    def _receive_messages(self):
        while self.running:
            msg = self.bus.recv(1.0)  # 超时1秒
            if msg is not None:
                #return msg
                # 以下可以输出至终端
                timestamp = datetime.datetime.now().strftime("%H:%M:%S.%f")[:-3]
                print(f"[{timestamp}] RX: ID=0x{msg.arbitration_id:03X}, DLC={len(msg.data)}, Data={msg.data.hex(' ').upper()}")


class VirtualECU:
    def __init__(self, ecu_name, can_bus, ecu_id):
        self.name = ecu_name
        self.can_bus = can_bus  # 关联到CAN总线
        self.ecu_id = ecu_id    # ECU的CAN ID
        self.running = False
        self.process_thread = Thread(target=self._process_messages)
        self.diagnostic_session = 0  # 0=默认会话, 1=扩展会话
        print(f"虚拟ECU {ecu_name} (ID=0x{ecu_id:X}) 已初始化")

    def start(self):
        self.running = True
        self.process_thread.start()
        print(f"虚拟ECU {self.name} 已启动")

    def stop(self):
        self.running = False
        self.process_thread.join()
        print(f"虚拟ECU {self.name} 已关闭")

    def _process_messages(self):
        while self.running:
            # 模拟ECU处理逻辑 - 这里可以添加UDS诊断服务处理
            time.sleep(0.2)
            msg = self.bus.recv(1.0)  # 超时1秒
            if msg is not None:
                # 处理接收到的消息 (示例: 处理诊断请求) 
                if msg.data[2] == 0x19:  # 诊断请求
                    print(f"ECU {self.name} 收到诊断请求")
                    status_data = [0x07, 0x59, 0x02, 0xFF, 0x1B, 0x30,0x07,0x8B]
                    self.can_bus.send_message(self.ecu_id, bytes(status_data))


if __name__ == "__main__":
    # 创建虚拟CAN总线
    can_bus = VirtualCANBus()
    can_bus.start()

    # 创建虚拟ECU (例如发动机控制单元)
    engine_ecu = VirtualECU("Engine_ECU", can_bus, 0x7A9)
    engine_ecu.start()

    try:
        # 等待用户按下Ctrl+C结束程序
        print("程序正在运行，按Ctrl+C停止...")
        while True:
            time.sleep(1)  # 无限循环等待中断
    except KeyboardInterrupt:
        print("\n用户中断程序，正在关闭资源...")
    finally:
        #engine_ecu.stop()
        can_bus.stop()